/*
 * Protocol.cpp
 *
 *  Created on: 01/06/2011
 *      Author: wadi
 */

#include "protocol.h"

Protocol::Protocol()
:	logger_(log4cxx::Logger::getLogger("common.comm.protocol"))
{
}

Protocol::~Protocol()
{
}

std::vector<char> Protocol::buildStartScreenCast(Lesson* lesson)
{
  return buildMessage(START_SCREENCAST,xmlUtil.serializeLesson(*lesson));

}
std::vector<char> Protocol::buildStartAndSaveScreenCast(Lesson* lesson)
{
  return buildMessage(START_SCREENCAST_RECORDING,xmlUtil.serializeLesson(*lesson));

}
std::vector<char> Protocol::buildPlayScreenCast(Lesson* lesson)
{
  return buildMessage(START_SCREENCAST_PLAYBACK,xmlUtil.serializeLesson(*lesson));

}

std::vector<char> Protocol::buildStopScreenCast(Lesson* lesson)
{
  return buildMessage(STOP_SCREENCAST,xmlUtil.serializeLesson(*lesson));
}

std::vector<char> Protocol::buildStopListeningScreenCast(Lesson* lesson){
  return buildMessage(STOP_SCREENCAST_USER_REQUEST,xmlUtil.serializeLesson(*lesson));
}

std::vector<char> Protocol::buildScreencastFailed(Lesson* lesson)
{
  return buildMessage(SCREENCAST_NOT_AVAILABLE,xmlUtil.serializeLesson(*lesson));
}


std::vector<char> Protocol::buildChatMessage(ChatMessage* msg){
  return buildMessage(CHAT_MESSAGE,xmlUtil.serializeChatMessage(*msg));
}
std::string Protocol::getUsername(Operation& op)
{
  return op.getTokens()[0];
}

std::string Protocol::getPassword(Operation& op)
{
  return op.getTokens()[1];
}

User* Protocol::parseLoginMessage(Operation& op)
{
  return xmlUtil.parseUser(op.getData());
}

ChatMessage* Protocol::parseChatMessage(Operation& op)
{
  return xmlUtil.parseChatMessage(op.getData());
}


std::vector<char> Protocol::buildLoginRequest(std::string username,std::string password)
{
  std::string data=username +'\n'+password;
  return buildMessage(LOGIN_REQUEST,data);
}

std::vector<char> Protocol::buildLogoutRequest()
{
  return buildMessage(LOGOUT_REQUEST,"");
}

std::vector<char>  Protocol::buildLoginMessage(User* user)
{
  std::string message;
  if(user==NULL){
      return buildMessage(LOGIN_FAILED,"Usuario o contrasenia incorrecta");
  }else{
      std::string strUser=xmlUtil.serializeUser((*user));
      return buildMessage(LOGIN_SUCCESS,strUser);
  }
}

std::vector<char> Protocol::buildMessage(char type,std::string datos)
{
  // Buffer con tamanio del argumento, tipo y el dato
  unsigned int tamanioTotal = datos.size() + 1 + 4;
  unsigned int tamanioClave=datos.length();
  std::vector<char> respuesta(tamanioTotal);
  respuesta[0] =(int) type;
  respuesta[1] =(int) (tamanioClave & 0xff);
  respuesta[2] =(int) (tamanioClave >> 8) & 0xff;
  respuesta[3] =(int) (tamanioClave >> 16) & 0xff;
  respuesta[4] =(int) (tamanioClave >> 24) & 0xff;
  datos.copy(&respuesta[5], datos.size(), 0);

  LOG4CXX_DEBUG(logger_, "building message " << tamanioClave);
  return respuesta;
}

std::vector<char> Protocol::buildScreencastData(Lesson* lesson,unsigned char* data,int size,int pts)
{
  // Buffer con tamanio del argumento, tipo y el dato (4 mas del pts)
  unsigned int tamanioTotal = size + 1 + 4 +4;
  std::vector<char> respuesta(tamanioTotal);
  std::copy ( data, data+size, respuesta.begin()+9 );
  buildAvPacket(SCREENCAST_DATA,respuesta,tamanioTotal-5,pts);
  LOG4CXX_DEBUG(logger_, "building screencast data message size size: " << size);
  LOG4CXX_DEBUG(logger_, "building screencast data message vector size: " << respuesta.size());
  LOG4CXX_DEBUG(logger_, "building screencast data message tamanioTotal: " << tamanioTotal);
  return respuesta;
}

std::vector<char> Protocol::buildScreencastAudioData(Lesson* lesson,unsigned char* data,int size,int pts)
{
  // Buffer con tamanio del argumento, tipo y el dato (4 mas del pts)
  unsigned int tamanioTotal = size + 1 + 4 +4;
  std::vector<char> respuesta(tamanioTotal);
  std::copy ( data, data+size, respuesta.begin()+9 );
  buildAvPacket(SCREENCAST_AUDIO_DATA,respuesta,tamanioTotal-5,pts);
  LOG4CXX_DEBUG(logger_, "building screencast data message size size: " << size);
  LOG4CXX_DEBUG(logger_, "building screencast data message vector size: " << respuesta.size());
  LOG4CXX_DEBUG(logger_, "building screencast data message tamanioTotal: " << tamanioTotal);
  return respuesta;
}

void Protocol::buildAvPacket(char type,std::vector<char>& respuesta,int tamanio,int pts){
  respuesta[0] =(int) type;
  respuesta[1] =(int) (tamanio & 0xff);
  respuesta[2] =(int) (tamanio >> 8) & 0xff;
  respuesta[3] =(int) (tamanio >> 16) & 0xff;
  respuesta[4] =(int) (tamanio >> 24) & 0xff;
  respuesta[5] =(int) (pts & 0xff);
  respuesta[6] =(int) (pts >> 8) & 0xff;
  respuesta[7] =(int) (pts >> 16) & 0xff;
  respuesta[8] =(int) (pts >> 24) & 0xff;
}

std::vector<char> Protocol::buildFindAllShowsRequest()
{
  return buildMessage(FIND_SHOWS,"fs");
}

std::vector<char> Protocol::serializeShows( std::list<Course*> & courses, std::list<Lesson*> & lessonsToSerialize)
{
  std::string showsStr=xmlUtil.serializeShows(courses,lessonsToSerialize);
  return buildMessage(FIND_SHOWS,showsStr);
}

void Protocol::parseShows(Operation& op,std::list<Course*> & courses,std::list<Lesson*> & lessonsToSerialize)
{
  xmlUtil.parseShows(op.getData(),courses,lessonsToSerialize);
}

Lesson* Protocol::parseLesson(Operation& op)
{
  return xmlUtil.parseLesson(op.getData());
}

int Protocol::parsePts(Operation& op)
{
  int pts= op.readInteger(5);
  return pts;
}
